/**
  ETFDAQ Project
  \class TADAQ
  \brief The overall DAQ controlling class
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2024-08-17
  \date 2024-08-17 last modified

  \copyright Copyright (c) 2024 IMP-CAS with LGPLv3 LICENSE
*/

#ifndef TADAQ_h
#define TADAQ_h

#include <string>
#include <cstdint>
#include "daqstatus.h"

using std::string;

class TAController;
class TACrate;
class TACard;
class TAYaml;
class TAReadShm;
struct event_t;
struct block_t;

class TADAQ{
public:
  TADAQ(TAController *ctl);
  /// \param dev is the device name of the vme controller
  TADAQ(const string &dev);
  virtual ~TADAQ();

  virtual void Initialize();
  void SetDebug(bool opt = true){ fDebug = opt; }
  virtual void OpenFile(const string &comment = "");
  virtual void CloseFile(const string &comment = "");
  bool HasInitalized() const{ return fHasInitalized; }
  virtual void TerminalMode() const; ///< ctrl-C to end a run

  ///-- THE DAQ LOOP --///
  virtual void Run();
  virtual void ReadEvent(); ///< module buffer => controller buffer
  virtual void ClearData(); ///< clear the DAQ for next event
  virtual void ClearEventCounter(); ///< clear cards' event counter for next run
  /// \param isFull: write because the block is full
  virtual void DumpData(bool isFull = true); ///< controller buffer => disk and shm
  virtual void ClearShm(); ///< clean the shm to no data state
  // the following are just wrappers to the corresponding controller's methods //
  virtual void SuspendForIRQ(); ///< wait for an interrupt
  virtual bool IsIRQed(); ///< whether an IRQ has arrived
  virtual void EnableIRQ(); ///< enable or recover the controller's IRQ bits
  virtual void DropDead(); ///< disable the trigger
  virtual void Resurrect(); ///< recover the trigger
  virtual void DisableOnlineShm(){ fIsOnline = false; }
  void SetDaqStatus(EDAQSTA sta){ fDaqSta = sta; }

  TAController *GetController() const{ return fController; }
  TACrate *GetCrate() const{ return fCrate; }
  const TAYaml *GetConfig() const{ return fConfig; }
  const char *GetFileName() const;
  double GetFileSizeInMB() const;
  uint32_t GetCntEv() const{ return fEvIndex; }
  uint32_t GetCntBlk() const{ return fBlkIndex; }
  uint32_t GetEvLen() const;
  time_t StartTime() const{ return fT0; }
  EDAQSTA status() const{ return fDaqSta; }

protected:
  TAController *fController;
  TACrate *fCrate;
  const TAYaml *fConfig; ///< the user input
  bool fHasInitalized;
  bool fDebug;

  event_t *fEv; ///< points to the event aera of fBlock
  block_t *fBlock;
  uint32_t fEvIndex, fBlkIndex;

  int fdw; ///< file descriptor to the output data file
  string fDataDir, fFileName; ///< datadir: data directory
  TAReadShm *fShm; ///< responsible to read and write to the shared memeroy
  bool fIsOnline; ///< whether write data to shm for online monitoring

  time_t fT0; ///< start time of one DAQ run
  EDAQSTA fDaqSta; ///< the current daq status
};

#endif
